/**
* \file		Case.c
* \brief	Code des fonctions du module Case
* \details	C'est ici qu'est le code des accesseurs, mutateurs ainsi que
*		la fonction de test vérifant le bon fonctionnement du module
*		Case.
*		Une description de la structure Case est fournie à
*		la rubrique \link Case.h
*/

/* voir si on garde tous les includes */
#include "Case.h"
#include "Production.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

/*========================== Gestion de la mémoire ==========================*/

void initCase(Case *pcase, unsigned int xMax, unsigned int yMax, unsigned int zMax)
{
   pcase->terrain = NULL;
   setNouvProdCase(pcase, NULL);
   setTraversableCase(pcase, 0);
   pcase->nbPers = 0;
   setXCase(pcase, 0, xMax);
   setYCase(pcase, 0, yMax);
   setZCase(pcase, 0, zMax);
   setXAdjCase(pcase, 0);
   pcase->casesAdj = NULL;
}

void libereCase(Case *pcase)
{
   if(getCasesAdjCase(pcase) != NULL)
	{
	   free(pcase->casesAdj);
	}
   if(getProdCase(pcase) != NULL)
	{
	   detruireProd(getProdCase(pcase));
	}
}

/*============================= Accesseurs =============================*/

Terrain *getTerrainCase(const Case *pcase)
{
   return pcase->terrain;
}

Production *getProdCase(const Case *pcase)
{
   return pcase->prod;
}

char *getNomProdCase(const Case *pcase)
{
   if (getProdCase(pcase) == NULL)
	{
	   return NULL;
	}
   else
	{
	   return getNomProd(getProdCase(pcase));
	}
}

int getPourcentageProdCase(const Case *pcase)
{
   if (getProdCase(pcase) == NULL)
	{
	   return -1;
	}
   else
	{
	   return getPourcentageProd(getProdCase(pcase));
	}
}

int getVitesseProdCase(const Case *pcase)
{
   if (getProdCase(pcase) == NULL)
	{
	   return -1;
	}
   else
	{
	   return getVitesseProd(getProdCase(pcase));
	}

}

int getNbPersCase(const Case *pcase)
{
   return pcase->nbPers;
}

char getTraversableCase(const Case *pcase)
{
   return pcase->traversable;
}

unsigned int getXCase(const Case *pcase)
{
   return pcase->x;
}

unsigned int getYCase(const Case *pcase)
{
   return pcase->y;
}

unsigned int getZCase(const Case *pcase)
{
   return pcase->z;
}

unsigned int getXAdjCase(const Case *pcase)
{
   return pcase->xAdj;
}

Case **getCasesAdjCase(const Case *pcase)
{
   return pcase->casesAdj;
}

/*============================== Mutateurs ==============================*/

void setTerrainCase(Case *pcase, Terrain *pterrain)
{
   pcase->terrain = pterrain;
   pcase->traversable = getTraversableTerrain(pterrain);
}

void ajouteNbPersCase(Case *pcase, int varNbPers)
{
   pcase->nbPers += varNbPers;
   assert(pcase->nbPers >= 0);
}

void setNbPersCase(Case *pcase, int nouvNbPers)
{
   pcase->nbPers = nouvNbPers;
   assert(pcase->nbPers >= 0);   
}

void setTraversableCase(Case *pcase, char nouvTrav)
{
   pcase->traversable = nouvTrav;
}


void setNouvProdCase(Case *pcase, char *nomProd)
{
   Production *prodIni;
   if (nomProd != NULL)
	{
	   creerProd(&prodIni);
	   setNomProd(prodIni, nomProd);
	   pcase->prod = prodIni;
	}

   else
	{
	   pcase->prod = NULL;
	}
}

void ajoutePourcentageProdCase(Case *pcase, int pourcent)
{
   if(getProdCase(pcase) != NULL)
	{
	   ajoutePourcentageProd(getProdCase(pcase), pourcent);
	}
}

void ajouteVitesseProdCase(Case *pcase, int vitesse)
{
   if(getProdCase(pcase) != NULL)
	{
	   ajouteVitesseProd(getProdCase(pcase), vitesse);
	}
}

void setXCase(Case *pcase, unsigned int nouvX, unsigned int xMax)
{
   pcase->x = nouvX;
}

void setYCase(Case *pcase, unsigned int nouvY, unsigned int yMax)
{
   pcase->y = nouvY;
}

void setZCase(Case *pcase, unsigned int nouvZ, unsigned int zMax)
{
   pcase->z = nouvZ;
}

void setXAdjCase(Case *pcase, unsigned int nouvXAdj)
{
   pcase->xAdj = nouvXAdj;
}

void setIemeCaseAdjCase(Case *pcase, unsigned int i, Case *pcaseAdj)
{
   pcase->casesAdj[i] = pcaseAdj;
}
/*========================== Autres fonctions ==========================*/
void enleveProdCase(Case *pcase)
{
   if(NULL != getProdCase(pcase))
	{
	   detruireProd(getProdCase(pcase));
	   setNouvProdCase(pcase, NULL);
	}
}

/*========================== Fonction de Test ==========================*/

void testCase()
{
   Case caseTest;
   Terrain *terrTest;
   Terrain *terrTest2;
   unsigned int xMax = 200;
   unsigned int yMax = 200;
   unsigned int zMax = 7;
   TabTerrains tableau;
   char *fichierDat = {"DatTerr"};
   int tailleTab;
   int i;
   int comp;
   int tabEnt[] = {1,5,50,-7};
   char *nomProd = "metal";

   tableau = creerTabTerrains(fichierDat);
   tailleTab = getNbCasesTabTerrains(&tableau);

   printf("Test de Case\n");

   printf("\tCréation et initialisation de la case\t\t");
   initCase(&caseTest, xMax, yMax, zMax);
   assert(caseTest.traversable == 0);
   assert(caseTest.nbPers == 0);
   assert(caseTest.x == 0);
   assert(caseTest.y == 0);
   assert(caseTest.z == 0);
   assert(caseTest.prod == NULL);
   printf("OK\n");

   printf("\tAffectation et récupération de valeurs\t\t");
   for(i=0; i<tailleTab; i++)
	{
	   terrTest2 = getTerrainTabTerrains(&tableau, i);
	   setTerrainCase(&caseTest, terrTest2);
	   terrTest = getTerrainCase(&caseTest);
	   assert(cmpTerrainNom(terrTest, getNomTerrain(terrTest2)) == 1);
	}

   comp = 0;
   for(i=0; i<5; i++)
	{
	   comp += i;
	   ajouteNbPersCase(&caseTest, i);
	   assert(getNbPersCase(&caseTest) == comp);

	   setXCase(&caseTest, i, xMax);
	   assert(getXCase(&caseTest) == i);

	   setYCase(&caseTest, i, yMax);
	   assert(getYCase(&caseTest) == i);

	   setZCase(&caseTest, i, zMax);
	   assert(getZCase(&caseTest) == i);
	}

   for(i=-2; i<5; i++)
	{
	   setTraversableCase(&caseTest, (char)i);
	   assert(getTraversableCase(&caseTest) == (char)i);
	}

   setNouvProdCase(&caseTest, nomProd);
   assert(0 == strcmp(getNomProdCase(&caseTest), nomProd));
   comp = 0;
   for(i=0; i<4; i++)
	{
	   ajoutePourcentageProdCase(&caseTest, tabEnt[i]);
	   ajouteVitesseProdCase(&caseTest, tabEnt[i]);
	   comp += tabEnt[i];
	   assert(comp == getPourcentageProdCase(&caseTest));
	   assert(comp == getVitesseProdCase(&caseTest));
	}

   printf("OK\n");

   printf("\tDésaffectation de production\t\t\t");
   enleveProdCase(&caseTest);
   assert(NULL == getProdCase(&caseTest));
   getNomProdCase(&caseTest);
   ajoutePourcentageProdCase(&caseTest, 3);
   ajouteVitesseProdCase(&caseTest, 3);
   printf("OK\n\n");
   libereCase(&caseTest);
   detruireTabTerrains(&tableau);
}
